package com.inspur.edp.formserver.viewmodel.rtwebapi;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.inspur.edp.bef.bizentity.GspBusinessEntity;
import com.inspur.edp.bef.bizentity.json.element.BizElementSerializer;
import com.inspur.edp.cef.designtime.api.element.GspAssociation;
import com.inspur.edp.cef.designtime.api.json.element.GspAssociationSerializer;
import com.inspur.edp.cef.designtime.api.util.MetadataUtil;
import com.inspur.edp.das.commonmodel.entity.element.GspCommonAssociation;
import com.inspur.edp.formserver.viewmodel.common.mapping.GspVoElementMapping;
import com.inspur.edp.formserver.viewmodel.util.ViewModelUtils;
import com.inspur.edp.formserver.vmmanager.exception.VmManagerException;
import com.inspur.edp.formserver.vmmanager.service.UpdateVirtualVoElementWithUdtService;
import com.inspur.edp.formserver.vmmanager.service.WebControllerService;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.entity.MetadataDto;
import com.inspur.edp.lcm.metadata.common.MetadataDtoConverter;
import com.inspur.edp.metadata.rtcustomization.api.CustomizationService;
import io.iec.edp.caf.commons.exception.ExceptionLevel;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

public class VMMetadataController {
  private final String EXCEPTIONCODE="vmMetadataRtWebApi";


  @Path("getbizObject/{beid}/{objid}")
  @GET
  @Produces(MediaType.APPLICATION_JSON)
  public String getBizObject(@PathParam("beid") String beid,@PathParam("objid") String objid,@QueryParam("path") String path,@QueryParam("bePkgName") String bePkgName) {
    GspBusinessEntity be=getBizEntity(path,bePkgName,beid);
    return WebControllerService.getInstance().getBizObject(be, objid);
  }

  /**
   * 保存运行时元数据
   * @param metadataDto
   * @return
   */
  @Path("saveMetadata")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public boolean saveMetadata(MetadataDto metadataDto) {
    if(metadataDto == null) {
      throw new VmManagerException("",EXCEPTIONCODE, "保存元数据DTO为空。",null, ExceptionLevel.Error,false);
    }
    GspMetadata metadata = MetadataDtoConverter.asMetadata(metadataDto);
    SpringBeanUtils.getBean(CustomizationService.class).save(metadata);
    return true;
  }

  @Path("checkvo")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public void checkKeywords(String jsonObject) {
    WebControllerService.getInstance().checkKeywords(jsonObject);
  }

  @Path("getVirtualVoAsso")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String getVirtualVoAsso(String info) {
    return WebControllerService.getInstance().getVirtualVoAsso(info,  (String path, String bePkgName, String beId) -> getBizEntity(path,bePkgName,beId));
  }

  @Path("virtualVoChooseUdt")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String updateVirtualVoUdtElementWhenChooseUdt(String info) {
    ObjectMapper mapper=new ObjectMapper();
    try {
      JsonNode node= mapper.readTree(info);
      String refUdtId=node.get("refUdtId").textValue();
      String path=node.get("path").textValue();
      String beElementJson=node.get("udtElementJson").textValue();
      return UpdateVirtualVoElementWithUdtService
          .getInstance().UpdateVariableWithRefUdtRT(refUdtId,path,beElementJson,true);
    } catch (JsonProcessingException e) {
      throw new RuntimeException(e);
    }

  }

  /**
   *
   * @param path
   * @param bePkgName
   * @param beId
   * @return
   */
  private GspBusinessEntity getBizEntity(String path, String bePkgName, String beId)
  {

    if (ViewModelUtils.checkNull(beId))
    {
      throw new VmManagerException("",EXCEPTIONCODE, "待获取的业务实体元数据id不可为空。",null, ExceptionLevel.Error,false);
    }
    GspMetadata metadata = MetadataUtil.getCustomMetadata(beId);
    if (!(metadata.getContent() instanceof GspBusinessEntity))
    {
      throw new VmManagerException("",EXCEPTIONCODE, String.format("无法加载id='%1$s'的业务实体元数据。", beId),null,ExceptionLevel.Error,false);
    }
    return (GspBusinessEntity) metadata.getContent();
  }

  /**
   * 转换BE字段
   * @param convertEleInfo
   * @return
   */
  @Path("convertBeElements")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String convertBeElementIdsToVmElements(String convertEleInfo) {
    return WebControllerService.getInstance().convertBeElementIdsToVmElements(convertEleInfo,
        (String path, String bePkgName, String beId) -> getBizEntity(path, bePkgName, beId));
  }

  @Path("addObject")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String addBizObject(String addObjInfo) {
    return WebControllerService.getInstance().addBizObject(addObjInfo,
        (String path, String bePkgName, String beId) -> getBizEntity(path, bePkgName, beId));
  }


  @Path("getBeAsso")
  @PUT
  @Produces(MediaType.APPLICATION_JSON)
  public String getBizAssoById(String info) {
    ObjectMapper mapper=new ObjectMapper();
    SimpleModule module =new SimpleModule();
    BizElementSerializer bizElementSerializer=new BizElementSerializer();
    GspAssociationSerializer associationDeserializer=new GspAssociationSerializer(bizElementSerializer);
    module.addSerializer(GspAssociation.class,associationDeserializer);
    mapper.registerModule(module);
    try {
      JsonNode node= mapper.readTree(info);
      String path = node.get("path").textValue();
      String voEleMappingJson = node.get("voEleMapping").textValue();
      String beAssoId = node.get("assoId").textValue();
      GspVoElementMapping voEleMapping = WebControllerService.getInstance().readVoEleMapping(voEleMappingJson);
      GspCommonAssociation bizAsso = WebControllerService.getInstance().getBizAsso(path, voEleMapping, beAssoId, this::getBizEntity);

      String bizAssoJson=mapper.writeValueAsString(bizAsso);
      return bizAssoJson;
    } catch (JsonProcessingException e) {
      throw new RuntimeException("GspAssociation序列化失败"+e);
    }
  }
}
